#!/usr/bin/python
#-----------------------------------------------------------------------------
# GUI for wherewasi
#
# Usage: 
#   wherewasi_gui.py
#
# Controls:
#   * drag left/right along top of window to zoom in/out
#   * drag the map to move around
#   * click on the map for a position menu
#       * set your own position, if the GPS didn't already do that
#       * set that location as a destination
#       * route to that point
#   * click on the top-left of the window for the main menu
#       * download routing data around your position
#       * browse geoRSS, wikipedia, and OSM points of interest
#       * select your mode of transport for routing
#           * car, bike, foot currently supported
#       * toggle whether the map is centred on your GPS position
#-----------------------------------------------------------------------------
# Copyright 2009, Graham Jones, based on pyroute gui.py by Oliver White
# Copyright 2007, Oliver White
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#-----------------------------------------------------------------------------
import pygtk
pygtk.require('2.0')
import gtk
import sys
import os
from math import sqrt
from time import *


#sys.path.append('./pyroute')

#GJ Modules
from parseGPX import parseGPX
#from geometry  import *
from tracklog_overlay import tracklog_overlay
from time import *
from mapwidget import MapWidget


class GuiBase:
  """Wrapper class for a GUI interface"""

  ui = '''<ui>
    <menubar name="MenuBar">
      <menu action="File">
        <menuitem action="Open"/>
        <menuitem action="Save"/>
        <menuitem action="SaveAs"/>
        <menuitem action="Export"/>
        <menuitem action="Quit"/>
      </menu>
      <menu action="Edit">
        <menuitem action="Properties"/>
      </menu>
      <menu action="Help">
        <menuitem action="Instructions"/>
        <menuitem action="About"/>
      </menu>
    </menubar>
    <toolbar name="Toolbar">
      <toolitem action="Quit"/>
      <separator/>
      <toolitem action="Open"/>
      <separator/>
      <toolitem action="Export"/>
      <separator/>
    </toolbar>
    </ui>'''

  def __init__(self,debug):
    self.debug = debug
    self.pgpx = None
    self.AnRes = None
    self.blockUpdateSpinButtons = False

# Delete any graph files to avoid displaying them in error.
    graph1fn = os.path.join(os.getcwd(), "gnuplot.png")
    if os.path.exists(graph1fn):
      print "Deleting existing graph file %s." % graph1fn
      os.remove(graph1fn)
    graph2fn = os.path.join(os.getcwd(), "gnuplot2.png")
    if os.path.exists(graph2fn):
      print "Deleting existing graph file %s." % graph2fn
      os.remove(graph2fn)
    

    # Create the window
    win = gtk.Window()
    win.set_title('wherewasi GUI')
    win.connect('delete-event', gtk.main_quit)
    ht = 500
    wd = int(ht*1.8)
    win.resize(wd,ht)
    win.move(50, gtk.gdk.screen_height() - ht)

    vbox1 = gtk.VBox()  # Main window vertical slices - menu/toolbar/main GUI 
                        #                                               area.
    vbox2 = gtk.VBox()  # left hand side of GUI - text boxes & graphs.
    vbox3 = gtk.VBox()  # contains text boxes etc. on LHS of GUI.
    vbox4 = gtk.VBox()  # right hand side of GUI - map and map control buttons.
    hbox1 = gtk.HBox()  # left/right split of main GUI window.

#    vbox = gtk.VBox()
#    vbox.set_homogeneous(False)

    # Create the menus and toolbar.
    uimanager = gtk.UIManager()
    self.accelgroup = uimanager.get_accel_group()
    win.add_accel_group(self.accelgroup)
    self.actiongroup = gtk.ActionGroup('UIManagerExample')
    self.actiongroup.add_actions([('Quit', gtk.STOCK_QUIT, '_Quit', 
                                   None, 'Quit the Program', self.menu_cb),
                                  ('File',None,'_File',None,None,None),
                                  ('Open',gtk.STOCK_OPEN,'_Open',
                                   None,None,self.menu_cb),
                                  ('Save',None,'_Save',None,None,self.menu_cb),
                                  ('SaveAs',None,'_SaveAs',None,None,self.menu_cb),
                                  ('Export',gtk.STOCK_CONVERT,'Export',
                                   None,None,self.menu_cb),
                                  ('Edit',None,'_Edit',None,None,None),
                                  ('Properties',None,'_Properties',None,None,self.menu_cb),
                                  ('Help',None,'_Help',None,None,None),
                                  ('Instructions',None,'_Instructions',None,None,self.menu_cb),
                                  ('About',None,'_About',None,None,self.menu_cb)
                                  ])

    uimanager.insert_action_group(self.actiongroup,0)
    uimanager.add_ui_from_string(self.ui)
    helpmenu = uimanager.get_widget('/MenuBar/Help')
    helpmenu.set_right_justified(True)

    menubar = uimanager.get_widget('/MenuBar')
    vbox1.pack_start(menubar,False)

    toolbar = uimanager.get_widget('/Toolbar')
    vbox1.pack_start(toolbar,False)

    vbox2 = gtk.VBox() # LHS of GUI - text boxes and graphs.

    vbox3 = gtk.VBox() # text boxes etc.
    # Create Data Selection Bit of GUI
    hbox = gtk.HBox()

#    vbox3.pack_start(gtk.Label("Analyse GPX File"),False)

#    hbox2 = gtk.HBox()
#    hbox2.pack_start(gtk.Label("GPX File"),False)
#    self.fnameTB = gtk.Entry(256)
#    hbox2.pack_start(self.fnameTB, False)
#    self.browseB = gtk.Button("Browse")
#    hbox2.pack_start(self.browseB,False)
#    self.loadB = gtk.Button("Load")
#    hbox2.pack_start(self.loadB, False)
#    vbox3.pack_start(hbox2, False)

    hbox2 = gtk.HBox()
    self.fileDataL = gtk.Label("No File Loaded")
    hbox2.pack_start(gtk.Label("File= "),False)
    hbox2.pack_start(self.fileDataL, False)
    vbox3.pack_start(hbox2, False)
    vbox3.pack_start(gtk.HSeparator())

    hbox2 = gtk.HBox()
    hbox2.pack_start(gtk.Label("Start Seg"),False)
    self.startSegADJ = gtk.Adjustment(0,0,0,1,0,0)
    self.startSegSB = gtk.SpinButton(self.startSegADJ)
    hbox2.pack_start(self.startSegSB,False)
    hbox2.pack_start(gtk.Label("Start Pt"),False)
    self.startPtADJ = gtk.Adjustment(0,0,0,1,0,0)
    self.startPtSB = gtk.SpinButton(self.startPtADJ)
    hbox2.pack_start(self.startPtSB, False)
    self.startSegLenL = gtk.Label('...')
    hbox2.pack_start(self.startSegLenL,False)
    vbox3.pack_start(hbox2, False)
    hbox2 = gtk.HBox()
    self.startPointL = gtk.Label("Start Point: ")
    hbox2.pack_start(self.startPointL,False)
    vbox3.pack_start(hbox2,False)

    vbox3.pack_start(gtk.HSeparator())
    hbox2 = gtk.HBox()
    hbox2.pack_start(gtk.Label("End Seg"),False)
    self.endSegADJ = gtk.Adjustment(-1,-1,0,1,0,0)
    self.endSegSB = gtk.SpinButton(self.endSegADJ)
    hbox2.pack_start(self.endSegSB, False)
    hbox2.pack_start(gtk.Label("End Pt"), False)
    self.endPtADJ = gtk.Adjustment(-1,-1,0,1,0,0)
    self.endPtSB = gtk.SpinButton(self.endPtADJ)
    hbox2.pack_start(self.endPtSB, False)
    self.endSegLenL = gtk.Label('...')
    hbox2.pack_start(self.endSegLenL,False)
    vbox3.pack_start(hbox2, False)
    hbox2 = gtk.HBox()
    self.endPointL   = gtk.Label("End Point  : ")
    hbox2.pack_start(self.endPointL,False)
    vbox3.pack_start(hbox2,False)
    vbox3.pack_start(gtk.HSeparator())
    
    # Create Output Part of GUI
    hbox2 = gtk.HBox()
    self.totalDistL = gtk.Label("Total Distance: xxx km")
    self.totalClimbL = gtk.Label("Total Climb:  xxx m")
    hbox2.pack_start(self.totalDistL,False)
    hbox2.pack_start(self.totalClimbL,False)
    vbox3.pack_start(hbox2,False)

    hbox2 = gtk.HBox()
    self.totalTimeL = gtk.Label("Total Time:  xxx hrs")
    hbox2.pack_start(self.totalTimeL,False)
    vbox3.pack_start(hbox2,False)

    hbox2 = gtk.HBox()
    self.avSpeedL = gtk.Label("Average Speed: xxx km/hr")
    self.maxSpeedL = gtk.Label("Maximum Speed:  xxx km/hr")
    hbox2.pack_start(self.avSpeedL,False)
    hbox2.pack_start(self.maxSpeedL,False)
    vbox3.pack_start(hbox2,False)

    vbox3.pack_start(gtk.HSeparator())
    vbox2.pack_start(vbox3, False)

    self.darea = gtk.DrawingArea()
    self.darea.connect("expose-event",self.drawGraph)
    self.darea2 = gtk.DrawingArea()
    self.darea2.connect("expose-event",self.drawGraph2)
    hbox2 = gtk.HBox()
    hbox2.pack_start(self.darea)
    hbox2.pack_start(gtk.VSeparator(),False)
    hbox2.pack_start(self.darea2)

    vbox2.pack_start(hbox2)



    # Events
#    self.browseB.connect("clicked",self.buttonCallback,"browseB")
#    self.loadB.connect("clicked",self.buttonCallback,"loadB")
    self.startSegADJ.connect("value-changed",
                             self.buttonCallback,
                             "SSAdjustment")
    self.startPtADJ.connect("value-changed",
                            self.buttonCallback,
                            "SPAdjustment")
    self.endSegADJ.connect("value-changed",
                           self.buttonCallback,
                           "ESAdjustment")
    self.endPtADJ.connect("value-changed",
                          self.buttonCallback,
                          "EPAdjustment")


    event_box = gtk.EventBox()
    event_box.connect("button_press_event", lambda w,e: self.pressed(e))
    event_box.connect("button_release_event", lambda w,e: self.released(e))
    event_box.connect("scroll-event", lambda w,e: self.scrolled(e))
    event_box.connect("motion_notify_event", lambda w,e: self.moved(e))
    event_box.connect("configure_event",self.configure_event_handler)
    
    # Create the map
    self.mapWidget = MapWidget()
    print "created mapWidget"
    event_box.add(self.mapWidget)


    vbox3 = gtk.VBox()
    hbox2 = gtk.HBox()
    zb = gtk.Button("+",gtk.STOCK_ZOOM_IN)
    zb.connect("clicked",self.buttonCallback,"zoomIn")
    hbox2.pack_start(zb,False)
    zb = gtk.Button("-",gtk.STOCK_ZOOM_OUT)
    zb.connect("clicked",self.buttonCallback,"zoomOut")
    hbox2.pack_start(zb,False)
    zb = gtk.Button("-",gtk.STOCK_ZOOM_FIT)
    zb.connect("clicked",self.buttonCallback,"zoomFit")
    hbox2.pack_start(zb,False)
    vbox3.pack_start(hbox2,False)
    vbox3.pack_start(event_box)

    print "adding vbox"
    hbox1.pack_start(vbox2)
    hbox1.pack_start(gtk.VSeparator(),False)
    
    hbox1.pack_start(vbox3)
    print "adding hbox to window"

    vbox1.pack_start(hbox1)
    win.add(vbox1)
    print "added hbox to window"
    
    # Finalise the window
    win.show_all()
    gtk.main()
    self.mapWidget.beforeDie()
    


  def menu_cb(self, act):
    print 'menu_cb- act=%s' % act
    name = act.get_name()
    print 'act.name=%s' % name

    if name == 'Open':
      if (self.debug): print 'Open'
      print "browseB pressed"
      dialog = gtk.FileChooserDialog("Open..",
                                     None,
                                     gtk.FILE_CHOOSER_ACTION_OPEN,
                                     (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                      gtk.STOCK_OPEN, gtk.RESPONSE_OK))
      response = dialog.run()
      if (response==gtk.RESPONSE_OK):
        self.fname = dialog.get_filename()
        print "selected filename=%s." % self.fname
      dialog.destroy()
      self.pgpx = parseGPX(self.fname,True,True)

      self.updateSpinButtons()
      self.getAnalysisResults()
      self.updateFileDataLabels()
      self.updateGraph()
      self.tlo = self.mapWidget.modules['tracklog_overlay']
      self.tlo.setGpx(self.pgpx)
      trkpt = self.pgpx.getTrkPt(0,0)
      lat = trkpt['lat']
      lon = trkpt['lon']
      self.mapWidget.setPosition(lat,lon,9)

    elif name == 'Save':
      if (self.debug): print 'Save'
    elif name == 'SaveAs':
      if (self.debug): print 'SaveAs'
    elif name == 'Export': 
      if (self.debug): print 'Export'
    elif name=='Quit':
      if (self.debug): print 'Quit'
      gtk.main_quit()
    elif name == 'Properties':
      if (self.debug): print 'Properties'
    elif name == 'Instructions':
      if (self.debug): print 'Instructions'
    elif name == 'About':
      if (self.debug): print 'About'
    else:
      print 'Oh No - I don\'t know what to do with action %s!!!' % name
      print 'going for the safe option and doing NOTHING!!!'



  def buttonCallback(self,widget,data=None):
    """Callback function that is called whenever one of teh GUI buttons
    is pressed.  Relies on the 'data' parameter passed to this function
    to decide which button was pressed, and what to do about it.
    """
    if self.debug: print "buttonCallback(): data=%s." % data

    if data == "browseB":
      if self.debug: print "browseB pressed"
#      dialog = gtk.FileChooserDialog("Open..",
#                                     None,
#                                     gtk.FILE_CHOOSER_ACTION_OPEN,
#                                     (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
#                                      gtk.STOCK_OPEN, gtk.RESPONSE_OK))
#      response = dialog.run()
#      if (response==gtk.RESPONSE_OK):
#        fname = dialog.get_filename()
#        if self.debug: print "selected filename=%s." % fname
#        self.fnameTB.set_text(fname)
#      dialog.destroy()
#    elif data == "loadB":
#      if self.debug:print "loadB pressed: loading %s" % self.fnameTB.get_text()
#      self.pgpx = parseGPX(self.fnameTB.get_text(),True,True)
#      trkpt = self.pgpx.getTrkPt(0,0)
#      lat = trkpt['lat']
#      lon = trkpt['lon']
#      mapWidget.setPosition(lat,lon,9)
#      self.updateSpinButtons()
#      self.getAnalysisResults()
#      self.updateFileDataLabels()
#      self.updateGraph()
#      self.updateTrackLog()
    elif data == "SSAdjustment" or \
          data == "SPAdjustment" or \
          data == "ESAdjustment" or \
          data == "EPAdjustment":
      print "Adjustment Changed - %s." % data
      if self.blockUpdateSpinButtons:
        if self.debug: print("UpdateSpinButtons blocked")
      else:
        self.updateSpinButtons()
        self.getAnalysisResults()
        self.updateFileDataLabels()
        self.updateGraph()
        self.updateTrackLog()
    elif data == "zoomIn":
      self.mapWidget.zoom(1)
    elif data == "zoomOut":
      self.mapWidget.zoom(-1)
    elif data == "zoomFit":
      if self.pgpx != None:
        trkpt = self.pgpx.getTrkPt(0,0)
        lat = trkpt['lat']
        lon = trkpt['lon']
        self.mapWidget.setPosition(lat,lon,9)
    else:
      if self.debug: print "oh no - I don't understand %s." % data


  def getAnalysisResults(self):
    """Analyse the GPX file between the specified start and end points
    and set the AnRes variable to the analysis results."""
    ss = int(self.startSegADJ.get_value())
    sp = int(self.startPtADJ.get_value())
    es = int(self.endSegADJ.get_value())
    ep = int(self.endPtADJ.get_value())
    print "getAnalysisResults() - ss=%d, sp=%d, es=%d, ep=%d" % \
        (ss,sp,es,ep)
    self.AnRes = self.pgpx.getTrackAnalysis(ss,sp,es,ep)
    print "self.AnRes=%s." % self.AnRes

  def updateFileDataLabels(self):
    """Updates the text labels in the GUI that contain information on the 
    GPX file and its analysis"""
    lbltxt = "%s,   %d Track Segments" % (self.pgpx.fname,
                                          self.pgpx.getNumTrkSeg())
    self.fileDataL.set_text(lbltxt)

    ss = int(self.startSegADJ.get_value())
    sp = int(self.startPtADJ.get_value())
    es = int(self.endSegADJ.get_value())
    ep = int(self.endPtADJ.get_value())
    sPt = self.pgpx.getTrkPt(ss,sp)
    ePt = self.pgpx.getTrkPt(es,ep)
    sTimeStruct = localtime(sPt['t'])
    eTimeStruct = localtime(ePt['t'])
    sTimeStr = strftime("%d/%m/%Y %X",sTimeStruct)
    eTimeStr = strftime("%d/%m/%Y %X",eTimeStruct)

    lbltxt = "Start Point: (%3.3f,%3.3f) - %s" % (sPt['lat'],
                                                  sPt['lon'],
                                                  sTimeStr)
    self.startPointL.set_text(lbltxt)
    lbltxt = "End   Point: (%3.3f,%3.3f) - %s" % (ePt['lat'],
                                                  ePt['lon'],
                                                  eTimeStr)
    self.endPointL.set_text(lbltxt)

    lbltxt = "Total Distance = %3.3f km" % self.AnRes['dist']
    self.totalDistL.set_text(lbltxt)
    lbltxt = "Total Climb = %3.0f m" % self.AnRes['climb']
    self.totalClimbL.set_text(lbltxt)
    time_hrs = self.AnRes['time'] / 3600.0
    lbltxt = "Total Time: %4.2f hrs" % time_hrs
    self.totalTimeL.set_text(lbltxt)
    lbltxt = "Average Speed: %4.2f km/hr" % self.AnRes['avSpeed']
    self.avSpeedL.set_text(lbltxt)
    lbltxt = "Maximum Speed: %4.2f km/hr" % self.AnRes['maxSpeed']
    self.maxSpeedL.set_text(lbltxt)


  def updateTrackLog(self):
    """Update the track log start and end points to match the values
    set on the GUI spin buttons.
    """
    ss = int(self.startSegADJ.get_value())
    sp = int(self.startPtADJ.get_value())
    es = int(self.endSegADJ.get_value())
    ep = int(self.endPtADJ.get_value())
    self.tlo.setDrawRange(ss,sp,es,ep)
    self.mapWidget.set("needRedraw", True)

  def updateGraph(self):
    """Update the elevation profile graph in the window.
    Creates a PNG file on disk using gnuplot, 
    then reads that into the window.
    """
    ss = int(self.startSegADJ.get_value())
    sp = int(self.startPtADJ.get_value())
    es = int(self.endSegADJ.get_value())
    ep = int(self.endPtADJ.get_value())
    profdata = self.pgpx.getProfileData(ss,sp,es,ep)
    #if self.debug: print "profdata=%s" % profdata

    timeArr = []
    distArr = []
    speedArr = []
    edistprofXY = []
    etimeprofXY = []
    dtimeprofXY = []
    stimeprofXY = []
    for rec in profdata:
      timeStruct = localtime(rec[0])
      timeStr = strftime("%d/%m/%Y %X",timeStruct)
      #print "%s \t %d \t %d \t %6.2f \t %6.0f" % \
      #    (timeStr,rec[0],rec[1], rec[2], rec[3])
      # elevation against distance
      edistprofXY.append([rec[2],rec[3]])
      # elevation against time
      etimeprofXY.append([rec[1]/3600.,rec[3]])
      # distance against time
      dtimeprofXY.append([rec[1]/3600.,rec[2]])
      # speed against time
      stimeprofXY.append([rec[1]/3600.,rec[4]])

      timeArr.append(rec[1]/3600.)
      distArr.append(rec[2])
      speedArr.append(rec[4])

    # Do Elevation Profile
    try:
      import Gnuplot
      g=Gnuplot.Gnuplot()
      g.title("GPX Track Elevation Profile")
      g.xlabel('Distance from Start (km)')
      g.ylabel('Elevation (m)')
      geometry = self.darea.window.get_geometry()
      print geometry
      termstr = "set terminal png size %d,%d" % (geometry[2],geometry[3])
      print termstr
      g(termstr)
      g('set yrange [-10:*]')
      g('set data style linespoints')
      graph1fn = os.path.join(os.getcwd(), "gnuplot.png")
      g('set output \"%s\"' % graph1fn)
      g.plot(edistprofXY)
      #g.hardcopy(filename="gnuplot.png", terminal='png')
      #raw_input('Please press return to continue...\n')
      g.reset()
    except: # python-gnuplot is not available or is broken
      print 'ERROR: gnuplot failed - either python gnuplot is not working' \
          ' or this is a bug!'

    try:
      import Gnuplot
      g=Gnuplot.Gnuplot()
      g.title("GPX Track Speed Profile")
      g.xlabel('Time (hrs)')
      g.ylabel('Speed (m/s)')
      geometry = self.darea.window.get_geometry()
      print geometry
      termstr = "set terminal png size %d,%d" % (geometry[2],geometry[3])
      print termstr
      g(termstr)
      g('set yrange [0:*]')
      g('set data style linespoints')
      graph2fn = os.path.join(os.getcwd(), "gnuplot2.png")
      g('set output \"%s\"' % graph2fn)
      #d = Gnuplot.Data(timeArr,speedArr,
      #                 with_="lines")
      #g.plot(d)
      g.plot(stimeprofXY)
      #g.hardcopy(filename="gnuplot.png", terminal='png')
      #raw_input('Please press return to continue...\n')
      g.reset()
    except: # python-gnuplot is not available or is broken
      print 'ERROR: gnuplot failed - either python gnuplot is not working' \
          ' or this is a bug!'

    self.darea.queue_draw()
    self.darea2.queue_draw()
    

  def drawGraph(self,area,event):
    """Actually draw the graph on the screen - assumes it is stored
    in "gnuplot.png" in the current working directory."""
    #print "drawGraph() starting"
    graph1fn = os.path.join(os.getcwd(), "gnuplot.png")

    if self.pgpx != None:
      if os.path.exists(graph1fn):
        style = area.get_style()
        gc = style.fg_gc[gtk.STATE_NORMAL]
        pixmap, mask = gtk.gdk.pixmap_create_from_xpm(
          area.window, style.bg[gtk.STATE_NORMAL], graph1fn)
        area.window.draw_drawable(gc, pixmap, 0, 0, 0, 0,
                                -1, -1)
      else:
        print "drawGraph() - no graph file %s." % graph1fn
    #print "drawGraph() complete"


  def drawGraph2(self,area,event):
    """Actually draw the graph on the screen - assumes it is stored
    in "gnuplot.png" in the current working directory."""
    #print "drawGraph2() starting"
    graph2fn = os.path.join(os.getcwd(), "gnuplot2.png")
    if self.pgpx != None:
      if os.path.exists(graph2fn):
        style = area.get_style()
        gc = style.fg_gc[gtk.STATE_NORMAL]
        pixmap, mask = gtk.gdk.pixmap_create_from_xpm(
          area.window, style.bg[gtk.STATE_NORMAL], graph2fn)
        area.window.draw_drawable(gc, pixmap, 0, 0, 0, 0,
                                  -1, -1)
      else:
        print "drawGraph2() - no graph file %s." % graph1fn
    #print "drawGraph() complete"



  def updateSpinButtons(self):
    """Set up the start and end point spin buttons"""
    # if we are in the process of updating the buttons, don't do anything,
    # or we will get into an endless loop.....the voice of experience...
    if self.blockUpdateSpinButtons:
      self.blockUpdateSpinButtons = True
      print "UpdateSpinButtons blocked - doing nothing"
      return

    print "updateSpinButtons() - blocking UpdateSpinButtons"
    self.blockUpdateSpinButtons = True

    print "updateSpinButtons() - updating Adjustments"
    ss = int(self.startSegADJ.get_value())
    sp = int(self.startPtADJ.get_value())
    es = int(self.endSegADJ.get_value())
    ep = int(self.endPtADJ.get_value())
    print "updateSpinButtons - sp=(%d,%d), ep=(%d,%d)" % (ss,sp,es,ep)

    self.startSegADJ.upper=self.pgpx.getNumTrkSeg()-1
    
    if sp > self.pgpx.getNumPts(ss)-1:
      sp = self.pgpx.getNumPts(ss)-1
      self.startPtADJ.value=sp
    self.startPtADJ.upper=self.pgpx.getNumPts(ss)-1
    lbltxt = " (0-%d)" % int(self.pgpx.getNumPts(ss)-1)
    if self.debug: print "lbltxt=%s" % lbltxt
    self.startSegLenL.set_text(lbltxt)

    self.endSegADJ.upper=self.pgpx.getNumTrkSeg()-1
    
    if ep > self.pgpx.getNumPts(es)-1:
      ep = self.pgpx.getNumPts(es)-1
    self.endPtADJ.upper=self.pgpx.getNumPts(es)-1
    lbltxt = " (-1-%d)" % int(self.pgpx.getNumPts(es)-1)
    if self.debug: print "lbltxt=%s" % lbltxt
    self.endSegLenL.set_text(lbltxt)

    print "updateSpinButtons() - unblocking updateSpinButtons"
    self.blockUpdateSpinButtons = False


  def configure_event_handler(self):
    print "configure_event_handler"

  def pressed(self, event):
    self.dragstartx = event.x
    self.dragstarty = event.y
    #print dir(event)
    #print "Pressed button %d at %1.0f, %1.0f" % (event.button, event.x, event.y)
    
    self.dragx = event.x
    self.dragy = event.y
    self.mapWidget.mousedown(event.x,event.y)

  def scrolled(self, event):
    if event.direction == gtk.gdk.SCROLL_UP:
      self.mapWidget.modules['projection'].setZoom(1, True)
      self.mapWidget.set("needRedraw", True)
      
    if event.direction == gtk.gdk.SCROLL_DOWN:
      self.mapWidget.modules['projection'].setZoom(-1, True)
      self.mapWidget.set("needRedraw", True)
      
  def moved(self, event):
    """Drag-handler"""

    self.mapWidget.handleDrag( \
      event.x,
      event.y,
      event.x - self.dragx, 
      event.y - self.dragy,
      self.dragstartx,
      self.dragstarty)

    self.dragx = event.x
    self.dragy = event.y
  def released(self, event):
    dx = event.x - self.dragstartx
    dy = event.y - self.dragstarty
    distSq = dx * dx + dy * dy
    if distSq < 4:
      self.mapWidget.click(event.x, event.y)


if __name__ == "__main__":
  program = GuiBase(True)
